package com.example.singing.view;

import com.example.singing.manager.CompetitionManager;
import com.example.singing.manager.ScoreManager;
import com.example.singing.manager.TeamManager;
import com.example.singing.model.Competition;
import com.example.singing.model.Score;
import com.example.singing.model.Team;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.PieChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Dashboard View
 */
public class DashboardView {
    private VBox view;
    private CompetitionManager competitionManager;
    private TeamManager teamManager;
    private ScoreManager scoreManager;
    
    // 保存表格引用以便刷新
    private TableView<Competition> competitionTable;
    private TableView<ScoreRankingItem> scoreTable;
    private HBox statsContainer;
    // 保存图表引用以便刷新
    private PieChart levelChart;
    private BarChart<String, Number> scoreChart;

    public DashboardView() {
        this.competitionManager = new CompetitionManager();
        this.teamManager = new TeamManager();
        this.scoreManager = new ScoreManager();
        createView();
    }

    /**
     * Create dashboard view
     */
    private void createView() {
        VBox mainContainer = new VBox(20);
        mainContainer.setPadding(new Insets(20));
        mainContainer.setStyle("-fx-background-color: #f5f5f5;");

        // Title
        Label title = new Label("总系统仪表盘");
        title.setFont(Font.font("Arial", FontWeight.BOLD, 28));
        title.setStyle("-fx-text-fill: #2c3e50;");
        mainContainer.getChildren().add(title);

        // Statistics cards area
        statsContainer = createStatsCards();
        mainContainer.getChildren().add(statsContainer);

        // Charts area
        HBox chartsContainer = createChartsContainer();
        mainContainer.getChildren().add(chartsContainer);

        // Data tables area
        HBox tablesContainer = createTablesContainer();
        mainContainer.getChildren().add(tablesContainer);

        this.view = mainContainer;
    }

    /**
     * 刷新数据显示
     */
    public void refreshData() {
        // 重新加载数据
        scoreManager.loadScores();
        teamManager.loadTeams();
        competitionManager.loadCompetitions();
        
        // 刷新统计卡片
        refreshStatsCards();
        
        // 刷新图表
        refreshCharts();

        // 刷新表格数据
        if (scoreTable != null) {
            List<ScoreRankingItem> rankingData = createScoreRankingData();
            scoreTable.setItems(FXCollections.observableArrayList(rankingData));
        }
        
        if (competitionTable != null) {
            List<Competition> recentCompetitions = competitionManager.getAllCompetitions().stream()
                    .sorted((c1, c2) -> c2.getDate().compareTo(c1.getDate()))
                    .limit(5)
                    .collect(Collectors.toList());
            competitionTable.setItems(FXCollections.observableArrayList(recentCompetitions));
        }
    }
    
    /**
     * 刷新统计卡片
     */
    private void refreshStatsCards() {
        if (statsContainer != null) {
            VBox parent = (VBox) statsContainer.getParent();
            int index = parent.getChildren().indexOf(statsContainer);
            parent.getChildren().remove(statsContainer);
            statsContainer = createStatsCards();
            parent.getChildren().add(index, statsContainer);
        }
    }

    /**
     * Create statistics cards
     */
    private HBox createStatsCards() {
        HBox statsContainer = new HBox(20);
        statsContainer.setAlignment(Pos.CENTER);

        // Get real-time data
        int totalCompetitions = competitionManager.getAllCompetitions().size();
        int totalTeams = teamManager.getAllTeams().size();
        int totalScores = scoreManager.getAllScores().size();
        int pendingScores = calculatePendingScores();

        // Create statistics cards
        VBox competitionCard = createStatCard("比赛总数", String.valueOf(totalCompetitions), "比赛", "#673ab7");
        VBox teamCard = createStatCard("参加团队", String.valueOf(totalTeams), "队伍", "#ff5722");
        VBox scoreCard = createStatCard("已评分", String.valueOf(totalScores), "完成", "#4caf50");
        VBox pendingCard = createStatCard("待评分", String.valueOf(pendingScores), "待", "#ff9800");

        statsContainer.getChildren().addAll(competitionCard, teamCard, scoreCard, pendingCard);
        return statsContainer;
    }

    /**
     * Create single statistics card
     */
    private VBox createStatCard(String title, String value, String icon, String color) {
        VBox card = new VBox(15);
        card.setPadding(new Insets(25));
        card.setAlignment(Pos.CENTER);
        card.setPrefWidth(200);
        card.setPrefHeight(120);
        card.setStyle("-fx-background-color: white; -fx-background-radius: 15; " +
                     "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 5);");

        // Icon
        Label iconLabel = new Label(icon);
        iconLabel.setFont(Font.font("Arial", 32));

        // Value
        Label valueLabel = new Label(value);
        valueLabel.setFont(Font.font("Arial", FontWeight.BOLD, 28));
        valueLabel.setStyle("-fx-text-fill: " + color + ";");

        // Title
        Label titleLabel = new Label(title);
        titleLabel.setFont(Font.font("Arial", 14));
        titleLabel.setStyle("-fx-text-fill: #78909c;");

        card.getChildren().addAll(iconLabel, valueLabel, titleLabel);
        return card;
    }

    /**
     * Create charts container
     */
    private HBox createChartsContainer() {
        HBox chartsContainer = new HBox(20);
        chartsContainer.setAlignment(Pos.CENTER);

        // Competition level distribution pie chart
        levelChart = createLevelDistributionChart();
        
        // Score distribution bar chart
        scoreChart = createScoreDistributionChart();

        chartsContainer.getChildren().addAll(levelChart, scoreChart);
        return chartsContainer;
    }

    /**
     * 刷新图表数据
     */
    private void refreshCharts() {
        if (levelChart != null) {
            Map<String, Long> levelCounts = competitionManager.getAllCompetitions().stream()
                    .collect(Collectors.groupingBy(Competition::getLevel, Collectors.counting()));

            ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList();
            for (Map.Entry<String, Long> entry : levelCounts.entrySet()) {
                pieChartData.add(new PieChart.Data(entry.getKey() + " (" + entry.getValue() + ")", entry.getValue()));
            }
            if (pieChartData.isEmpty()) {
                pieChartData.add(new PieChart.Data("暂无比赛", 1));
            }
            levelChart.setData(pieChartData);
        }

        if (scoreChart != null) {
            // 仅保留一个系列并更新
            scoreChart.getData().clear();
            CategoryAxis xAxis = (CategoryAxis) scoreChart.getXAxis();
            NumberAxis yAxis = (NumberAxis) scoreChart.getYAxis();
            xAxis.setLabel("分数范围");
            yAxis.setLabel("队伍个数");

            XYChart.Series<String, Number> series = new XYChart.Series<>();
            series.setName("队伍个数");

            Map<String, Long> scoreRanges = scoreManager.getAllScores().stream()
                    .collect(Collectors.groupingBy(this::getScoreRange, Collectors.counting()));

            String[] ranges = {"8.0-8.5", "8.5-9.0", "9.0-9.5", "9.5-10.0"};
            for (String range : ranges) {
                long count = scoreRanges.getOrDefault(range, 0L);
                series.getData().add(new XYChart.Data<>(range, count));
            }

            scoreChart.getData().add(series);
        }
    }

    /**
     * Create competition level distribution pie chart
     */
    private PieChart createLevelDistributionChart() {
        PieChart chart = new PieChart();
        chart.setTitle("比赛等级分布图");
        chart.setPrefSize(400, 300);
        chart.setStyle("-fx-background-color: white; -fx-background-radius: 15; " +
                      "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 5);");

        // Get actual data
        Map<String, Long> levelCounts = competitionManager.getAllCompetitions().stream()
                .collect(Collectors.groupingBy(Competition::getLevel, Collectors.counting()));

        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList();
        for (Map.Entry<String, Long> entry : levelCounts.entrySet()) {
            pieChartData.add(new PieChart.Data(entry.getKey() + " (" + entry.getValue() + ")", entry.getValue()));
        }

        // If no data, show default data
        if (pieChartData.isEmpty()) {
            pieChartData.add(new PieChart.Data("暂无比赛", 1));
        }

        chart.setData(pieChartData);
        return chart;
    }

    /**
     * Create score distribution bar chart
     */
    private BarChart<String, Number> createScoreDistributionChart() {
        CategoryAxis xAxis = new CategoryAxis();
        NumberAxis yAxis = new NumberAxis();
        BarChart<String, Number> chart = new BarChart<>(xAxis, yAxis);
        
        chart.setTitle("分数分布图");
        chart.setPrefSize(400, 300);
        chart.setStyle("-fx-background-color: white; -fx-background-radius: 15; " +
                      "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 5);");

        xAxis.setLabel("分数范围");
        yAxis.setLabel("队伍个数");

        XYChart.Series<String, Number> series = new XYChart.Series<>();
        series.setName("队伍个数");

        // Count score distribution
        Map<String, Long> scoreRanges = scoreManager.getAllScores().stream()
                .collect(Collectors.groupingBy(this::getScoreRange, Collectors.counting()));

        // Ensure all ranges have data
        String[] ranges = {"8.0-8.5", "8.5-9.0", "9.0-9.5", "9.5-10.0"};
        for (String range : ranges) {
            long count = scoreRanges.getOrDefault(range, 0L);
            series.getData().add(new XYChart.Data<>(range, count));
        }

        chart.getData().add(series);
        return chart;
    }

    /**
     * Get score range
     */
    private String getScoreRange(Score score) {
        double finalScore = score.getFinalScore();
        if (finalScore >= 8.0 && finalScore < 8.5) return "8.0-8.5";
        if (finalScore >= 8.5 && finalScore < 9.0) return "8.5-9.0";
        if (finalScore >= 9.0 && finalScore < 9.5) return "9.0-9.5";
        if (finalScore >= 9.5 && finalScore <= 10.0) return "9.5-10.0";
        return "Other";
    }

    /**
     * Create data tables container
     */
    private HBox createTablesContainer() {
        HBox tablesContainer = new HBox(20);
        tablesContainer.setAlignment(Pos.CENTER);

        // Recent competitions table
        VBox recentCompetitionsBox = createRecentCompetitionsTable();
        
        // Score ranking table
        VBox scoreRankingBox = createScoreRankingTable();

        tablesContainer.getChildren().addAll(recentCompetitionsBox, scoreRankingBox);
        return tablesContainer;
    }

    /**
     * Create recent competitions table
     */
    private VBox createRecentCompetitionsTable() {
        VBox container = new VBox(10);
        container.setPrefWidth(500);
        container.setStyle("-fx-background-color: white; -fx-background-radius: 15; " +
                          "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 5);");
        container.setPadding(new Insets(20));

        Label title = new Label("最近比赛");
        title.setFont(Font.font("Arial", FontWeight.BOLD, 16));
        title.setStyle("-fx-text-fill: #2c3e50;");

        competitionTable = new TableView<>();
        competitionTable.setPrefHeight(250);

        // Create columns
        TableColumn<Competition, String> nameCol = new TableColumn<>("比赛名");
        nameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
        nameCol.setPrefWidth(150);

        TableColumn<Competition, String> dateCol = new TableColumn<>("日期");
        dateCol.setCellValueFactory(new PropertyValueFactory<>("date"));
        dateCol.setPrefWidth(100);

        TableColumn<Competition, String> levelCol = new TableColumn<>("级别");
        levelCol.setCellValueFactory(new PropertyValueFactory<>("level"));
        levelCol.setPrefWidth(80);

        TableColumn<Competition, String> ruleCol = new TableColumn<>("评分规则");
        // Competition 字段为 scoringRule，对应 getter 为 getScoringRule
        ruleCol.setCellValueFactory(new PropertyValueFactory<>("scoringRule"));
        ruleCol.setPrefWidth(120);

        competitionTable.getColumns().addAll(nameCol, dateCol, levelCol, ruleCol);

        // Get recent 5 competitions
        List<Competition> recentCompetitions = competitionManager.getAllCompetitions().stream()
                .sorted(java.util.Comparator.comparing(Competition::getDate,
                        java.util.Comparator.nullsLast(String::compareTo)).reversed())
                .limit(5)
                .collect(Collectors.toList());

        competitionTable.setItems(FXCollections.observableArrayList(recentCompetitions));

        container.getChildren().addAll(title, competitionTable);
        return container;
    }

    /**
     * Create score ranking table
     */
    private VBox createScoreRankingTable() {
        VBox container = new VBox(10);
        container.setPrefWidth(500);
        container.setStyle("-fx-background-color: white; -fx-background-radius: 15; " +
                          "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 5);");
        container.setPadding(new Insets(20));

        Label title = new Label("分数直观图");
        title.setFont(Font.font("Arial", FontWeight.BOLD, 16));
        title.setStyle("-fx-text-fill: #2c3e50;");

        scoreTable = new TableView<>();
        scoreTable.setPrefHeight(250);

        // Create columns
        TableColumn<ScoreRankingItem, Integer> rankCol = new TableColumn<>("排名");
        rankCol.setCellValueFactory(new PropertyValueFactory<>("rank"));
        rankCol.setPrefWidth(50);

        TableColumn<ScoreRankingItem, String> teamCol = new TableColumn<>("队名");
        teamCol.setCellValueFactory(new PropertyValueFactory<>("teamName"));
        teamCol.setPrefWidth(120);

        TableColumn<ScoreRankingItem, String> competitionCol = new TableColumn<>("比赛");
        competitionCol.setCellValueFactory(new PropertyValueFactory<>("competitionName"));
        competitionCol.setPrefWidth(120);

        TableColumn<ScoreRankingItem, Double> scoreCol = new TableColumn<>("分数");
        scoreCol.setCellValueFactory(new PropertyValueFactory<>("score"));
        scoreCol.setPrefWidth(80);

        TableColumn<ScoreRankingItem, String> levelCol = new TableColumn<>("比赛等级");
        levelCol.setCellValueFactory(new PropertyValueFactory<>("level"));
        levelCol.setPrefWidth(80);

        scoreTable.getColumns().addAll(rankCol, teamCol, competitionCol, scoreCol, levelCol);

        // Get score ranking data
        List<ScoreRankingItem> rankingData = createScoreRankingData();
        scoreTable.setItems(FXCollections.observableArrayList(rankingData));

        container.getChildren().addAll(title, scoreTable);
        return container;
    }

    /**
     * Create score ranking data
     */
    private List<ScoreRankingItem> createScoreRankingData() {
        List<ScoreRankingItem> rankingData = new ArrayList<>();
        
        // Get all scores, sorted by score
        List<Score> sortedScores = scoreManager.getAllScores().stream()
                .sorted((s1, s2) -> Double.compare(s2.getFinalScore(), s1.getFinalScore()))
                .limit(10)
                .collect(Collectors.toList());

        int rank = 1;
        for (Score score : sortedScores) {
            Team team = teamManager.getTeamById(score.getTeamId());
            Competition competition = competitionManager.getCompetitionById(score.getCompetitionId());
            
            String teamName = team != null ? team.getName() : "Unknown Team";
            String competitionName = competition != null ? competition.getName() : "Unknown Competition";
            String level = competition != null ? competition.getLevel() : "Unknown";
            
            rankingData.add(new ScoreRankingItem(rank++, teamName, competitionName, score.getFinalScore(), level));
        }

        return rankingData;
    }

    /**
     * Calculate pending scores count
     */
    private int calculatePendingScores() {
        // Here you can calculate pending scores based on actual business logic
        // For example: teams that have no scores
        int totalTeams = teamManager.getAllTeams().size();
        int scoredTeams = scoreManager.getAllScores().size();
        return Math.max(0, totalTeams - scoredTeams);
    }

    /**
     * Get view
     */
    public VBox getView() {
        return view;
    }

    /**
     * Score ranking data item
     */
    public static class ScoreRankingItem {
        private int rank;
        private String teamName;
        private String competitionName;
        private double score;
        private String level;

        public ScoreRankingItem(int rank, String teamName, String competitionName, double score, String level) {
            this.rank = rank;
            this.teamName = teamName;
            this.competitionName = competitionName;
            this.score = score;
            this.level = level;
        }

        // Getters
        public int getRank() { return rank; }
        public String getTeamName() { return teamName; }
        public String getCompetitionName() { return competitionName; }
        public double getScore() { return score; }
        public String getLevel() { return level; }
    }
}